#include "stdafx.h"
#include "secret_sharing_CRT.h"
#ifdef BIG_NUMBERS
#include "..\Lab1_Large_numbers\__uintX2.h"
#endif

typedef
#ifdef BIG_NUMBERS
__uintX2<__int64>
#else
unsigned __int64
#endif
num;



// global variables
int total_number, threshold;

dealer_CRT<num>* dealer;
ss_players<share_item_CRT<num> > players;

void distribute(num secret)
{
	dealer =  new dealer_CRT<num>(threshold, total_number);
	// prepare
	const secret_CRT<num> s(secret);

	players.clear();
	for(int i = 0; i < total_number; ++i)
	{
		//ss_player<share_item_CRT<num> > player;
		players.push_back(new ss_player<share_item_CRT<num> >());
	}

	dealer->distribute_secret(&s, players);
}

num restore(int *players_numbers, int size)
{
	ss_players<share_item_CRT<num> > new_players;
	for(int i = 0; i < size; ++i)
	{
		new_players.push_back(players[players_numbers[i]]);
	}
	
	if(dealer == NULL) throw "Set the parameters in first!";
	secret_CRT<num>* restored_secret = dealer->restore_secret(new_players);
	return restored_secret->get_secret();
}
	
void show_main_menu();
void handle_params_menu();
void handle_distrib_secret_menu();
void handle_restore_secret_menu();



int main(int argc, char* argv[])
{
	if(argc > 1)
	{
		// put the code for working with 
		// command line arguments here
		return 0;
	}
	
	// the main menu
	int alternate;
	do
	{
		try{
		show_main_menu();
		scanf_s("%u", &alternate);
		system("cls");
		switch(alternate)
		{
		case 1:
			handle_params_menu();
			break;
		case 2:
			handle_distrib_secret_menu();
			break;
		case 3:
			handle_restore_secret_menu();
			break;
		default:
			printf("There is no such alternate. Try again.\n");
			break;
		}
		printf("\n");
		
		}

		catch(char* e)
		{
			printf(e);
			printf("\n\n");
		}
	}
	while(alternate!=4);
	
	return 0;
	// end of main menu
}

void show_main_menu()
{
	printf("1. Set the parameters.\n"); 
	printf("2. Distribute the secret.\n");
	printf("3. Restore the secret.\n");
	printf("4. Quit the service.\n");
}


void handle_params_menu()
{
	printf ("Enter the total numbers of players: ");
	scanf_s ("%u",&total_number);  

	printf ("Enter the threshold of players: ");
	scanf_s ("%u",&threshold);
}

void handle_distrib_secret_menu()
{
	num secret(0);
	printf ("Enter the secret: ");
	scanf_s ("%lu",&secret); 
	distribute(secret);
}

void handle_restore_secret_menu()
{
	int* players_for_restore = new int[total_number];
	int size = 0;
	int alternate;
	do
	{
		printf("1. Add new player.\n");
		printf("2. Done.\n");
		scanf_s ("%u",&alternate); 

		switch(alternate)
		{
		case 1:
			int n;
			printf("Enter the number of player:");
			scanf_s ("%u",&n);
			if((n < 0) || (n >= total_number)) throw "Incorrect number";

			if(size >= total_number) throw "Too many players";
			players_for_restore[size++] = n;
			break;
		case 2:
			break;
		default:
			printf("There is no such alternate. Try again.\n");
			break;
		}
		printf("\n");
	}
	while(alternate!=2);
	

	num restored = restore(players_for_restore, size);
	//printf("restored secret is  %d\n", restored);
	
	printf("Restored secret is: %u", restored);
}